#include "InterestRateBondIssuance.h"
#include <core/StyleMgr.h>
#include <core/ImageMgr.h>
#include <QDate>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QStackedLayout>
#include <QMouseEvent>
#include <widgets/STabCtrl.h>
#include "InterestRateBondList.h"
#include "InterestRateBondChart.h"
#include "../StringResource.h"
#include "bondlib/SSVContainer.h"

namespace {
	int getMonthDay(int year, int month) {
		assert(month >= 1 && month <= 12);
		switch (month) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12: return 31;
		case 2: return (((year % 4) == 0) || ((year % 400) == 0) ? 29 : 28);
		default: return 30;
		}
	}

	int timeToInt(const QDate& tm) {
		return tm.year() * 10000 + tm.month() * 100 + tm.day();
	}
}

InterestRateBondIssuance::InterestRateBondIssuance(QWidget* p)
	: SDialog(p),
	  m_dateTab(nullptr),
	  m_periodTab(nullptr),
	  m_viewTypeTab(nullptr),
	  m_list(nullptr),
	  m_chart(nullptr)
{
	setTitle(NewStringTable::strFixedIncomeTitle(1));

	QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(this->layout());
	if (!layout)return;
	layout->setContentsMargins(4, 0, 4, 4);

	QHBoxLayout* tabLayout = new QHBoxLayout();
	tabLayout->setSpacing(4);
	m_viewTypeTab = new STabCtrl(this);
	m_viewTypeTab->addTab(NewStringTable::strFixedIncomeViewType(0));//列
	m_viewTypeTab->addTab(NewStringTable::strFixedIncomeViewType(1));//图
	m_viewTypeTab->selectTab(VIEW_LIST);
	m_viewTypeTab->setFixedSize(48, 24);
	tabLayout->addWidget(m_viewTypeTab);

	m_dateTab = new STabCtrl(this);
	m_dateTab->addTab(NewStringTable::strFixedIncomeGovBondIssuance(6));
	m_dateTab->addTab(NewStringTable::strFixedIncomeGovBondIssuance(7));
	m_dateTab->selectTab(DATE_WEEK);
	m_dateTab->setFixedSize(48, 24);
	tabLayout->addWidget(m_dateTab);

	m_periodTab = new STabCtrl(this);
	m_periodTab->setFixedHeight(24);
	m_periodTab->addTab(NewStringTable::strFixedIncomeGovBondIssuance(0));
	m_periodTab->addTab(NewStringTable::strFixedIncomeGovBondIssuance(1));
	m_periodTab->addTab(NewStringTable::strFixedIncomeGovBondIssuance(2));
	m_periodTab->selectTab(PERIOD_CUR);
	tabLayout->addWidget(m_periodTab);
	tabLayout->addStretch();
	layout->addLayout(tabLayout);
	layout->addSpacing(4);

	QStackedLayout* stackLayout = new QStackedLayout();
	m_list = new InterestRateBondList(this);
	stackLayout->addWidget(m_list);
	m_chart = new InterestRateBondChart(this);
	stackLayout->addWidget(m_chart);
	layout->addLayout(stackLayout);

	connect(m_dateTab, &STabCtrl::tabSelected, this, &InterestRateBondIssuance::onTabSelected);
	connect(m_viewTypeTab, &STabCtrl::tabSelected, stackLayout, &QStackedLayout::setCurrentIndex);
	connect(m_viewTypeTab, &STabCtrl::tabSelected, this, &InterestRateBondIssuance::onTabSelected);
	connect(m_periodTab, &STabCtrl::tabSelected, this, &InterestRateBondIssuance::onTabSelected);
	onUpdateListData();
}

SDialog* InterestRateBondIssuance::clone(QWidget* parent)
{
	return new InterestRateBondIssuance(parent);
}

void InterestRateBondIssuance::onTabSelected(int index)
{
	QObject* obj = QObject::sender();
	STabCtrl* cb = qobject_cast<STabCtrl*>(obj);
	if (cb == m_viewTypeTab) {//图、列切换
		onTabViewTypeSelected();
	}
	else if (cb == m_dateTab) {//周月切换
		onTabDateSelected();
	}
	else if (cb == m_periodTab) {//上周（月）、本周（月）、下周（月）切换
		onTabPeriodSelected();
	}
}

void InterestRateBondIssuance::onTabViewTypeSelected()
{
	if (m_viewTypeTab->getSelTab() == VIEW_CHART) {
		m_periodTab->setVisible(false);
		onUpdateChartData();
	}
	else {
		m_periodTab->setVisible(true);
		onUpdateListData();
	}
}

void InterestRateBondIssuance::onTabDateSelected()
{
	updateTab(getCurrentDateType());
	if (m_viewTypeTab->getSelTab() == VIEW_CHART) {
		onUpdateChartData();
	}
	else {
		onUpdateListData();
	}
}

void InterestRateBondIssuance::onTabPeriodSelected()
{
	onUpdateListData();
}

InterestRateBondIssuance::DateType InterestRateBondIssuance::getCurrentDateType() const
{
	if (m_dateTab) {
		return (DateType)m_dateTab->getSelTab();
	}
	return DATE_WEEK;
}

void InterestRateBondIssuance::updateTab(DateType type)
{
	if (m_periodTab) {
		int nSel = m_periodTab->getSelTab();
		for (int i = 0; i < m_periodTab->getTabCount(); i++) {
			int offset = (type == DATE_WEEK ? 0 : 3);
			m_periodTab->setTabText(i,NewStringTable::strFixedIncomeGovBondIssuance(i + offset));
		}
		m_periodTab->selectTab(nSel);
	}
}

void InterestRateBondIssuance::onUpdateListData()
{
	DateType dateType = getCurrentDateType();
	int periodTab = m_periodTab->getSelTab();
	int dayFrom = 0, dayTo = 0;
	getStartEndDate(dateType, (Period)periodTab, dayFrom, dayTo);

	std::vector<int> bondIndexs;
	getBondIndex(dayFrom, dayTo, bondIndexs);
	m_list->setBondIndexs(bondIndexs);
}

void InterestRateBondIssuance::onUpdateChartData() 
{
	std::map<int, CRateBondList> chartData;
	std::vector<Period> periods = { PERIOD_PRE, PERIOD_CUR, PERIOD_NEXT };
	DateType dateType = getCurrentDateType();
	std::vector<int> bondIndexs;
	for (auto period : periods) {
		int dayFrom = 0, dayTo = 0;
		getStartEndDate(dateType, period, dayFrom, dayTo);
		getBondIndex(dayFrom, dayTo, bondIndexs);
		chartData[period].m_List.assign(bondIndexs.begin(), bondIndexs.end());
	}
	m_chart->setDate(dateType, &chartData);
}

void InterestRateBondIssuance::getStartEndDate(DateType dateType, Period period, int& dayFrom, int& dayTo) {
	QDate fromTime, toTime;
	QDateTime currentTime = QDateTime::fromTime_t(CSSVContainer::GetServerTime());

	if (dateType == DATE_WEEK) {//周
		int weekday = currentTime.date().dayOfWeek();
		weekday -= 1;

		//本周
		fromTime = currentTime.date().addDays(-weekday);
		toTime = fromTime.addDays(6);

		if (period == PERIOD_PRE) { //上周
			fromTime = fromTime.addDays(-7);
			toTime = toTime.addDays(-7);
		}
		else if (period == PERIOD_NEXT) { //下周
			fromTime = fromTime.addDays(7);
			toTime = toTime.addDays(7);
		}
	}
	else if (dateType == DATE_MONTH) { //月
		int year = currentTime.date().year();
		int month = currentTime.date().month();
		int day = currentTime.date().day();

		if (period == PERIOD_PRE) { //上月
			month -= 1;
			if (month < 1) {
				year -= 1;
				month = 12;
			}
		}
		else if (period == PERIOD_NEXT) { //下月
			month += 1;
			if (month > 12) {
				year += 1;
				month = 1;
			}
		}
		int days = getMonthDay(year, month);
		fromTime = QDate(year, month, 1);
		toTime = QDate(year, month, days);
	}
	dayFrom = timeToInt(fromTime);
	dayTo = timeToInt(toTime);
}

bool InterestRateBondIssuance::getBondIndex(int dayFrom, int dayTo, std::vector<int>& vecBonds) {
	vecBonds.clear();
	CBondContainer& bc = CBondContainer::instance();
	CSSVContainer& ssv = CSSVContainer::availableBond();

	int sz = ssv.GetSize();
	if (sz <= 0) {
		return false;
	}

	for (int i = 0; i < sz; i++) {
		int bondIndex = ssv.GetAt(i);
		if (!bc.IsValidIndex(bondIndex)) {
			continue;
		}

		const CBondInfo& bi = bc.ElementAtR(bondIndex);
		int date = atoi(bi.GetIssueStartDate());
		if (date<dayFrom || date>dayTo) {
			continue;
		}

		if (!bi.IsCNYBond())continue;//排除非人民币债券
		if (!bi.IsRatingDebt())continue;
		if (bi.IsBondCenter())continue;//排除央票
		if (bi.IsExchange() && bi.IsCrossMarket()) {//跨市场券，只显示银行间，没有银行间则显示上交所
			do {
				int bondIndex2 = bc.GetBondIndex(bi.GetBondKey(), CBondContainer::lmCIB);
				if (bc.IsValidIndex(bondIndex2)) {//找到银行间券
					bondIndex = bondIndex2;
					break;
				}
				bondIndex2 = bc.GetBondIndex(bi.GetBondKey(), CBondContainer::lmSSE);
				if (bc.IsValidIndex(bondIndex2)) {//找到上交所券
					bondIndex = bondIndex2;
					break;
				}
			} while (0);
		}

		if (std::find(vecBonds.begin(), vecBonds.end(), bondIndex) == vecBonds.end()) {
			vecBonds.push_back(bondIndex);
		}
	}
	return true;
}

